﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Skybot.NewWork.Graph
{
    /// <summary>
    /// 主要页面
    /// </summary>
    public partial class MainPage : UserControl
    {
        /// <summary>
        /// 定时器
        /// </summary>
        System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
        /// <summary>
        /// 构造函数
        /// </summary>
        public MainPage()
        {
            InitializeComponent();
            Loaded += MainPage_Loaded;
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            Test();
        }

        void Test()
        {
 
            //canvasLine.Children.Add(PathCommon.Draw(
            //    new Point(45, 36),
            //    new Point(180, 20),
            //    new Point(350, 360)
            //    ));


            timer.Tick += (s, e) =>
            {
                timer.Stop();
                //画圆
                DrawEllipse();
            };
            timer.Interval = TimeSpan.FromSeconds(0.1);
            timer.Start();
        }

        #region 将点转换成为圆

        /// <summary>
        /// 创建椭圆
        /// </summary>
        public void DrawEllipse()
        {
            //用于生成随机数的功能 
            random.Next(1, (int)ActualHeight / 10);
            int num = random.Next((int)ActualHeight / 25, (int)ActualHeight / 15);
            //产生随机点
            List<PointElement> myPoints = CreateFraments(this.ActualWidth * 0.8, this.ActualHeight * 0.8, num);
            foreach (PointElement pt in myPoints)
            {
                string photo = Photo;
 
                Ellipse el = new Ellipse()
                {
                    Fill = new ImageBrush()
                    {
                        ImageSource = new System.Windows.Media.Imaging.BitmapImage(new Uri(photo, UriKind.Relative)),
                    },
                    StrokeThickness = pt.StrokeThickness,
                    Stroke = new SolidColorBrush(pt.Color),
                    Height = pt.Radius,
                    Width = pt.Radius,
                };
                pt.Title =  PhotoName( int.Parse(  photo.Substring("/imgs/".Length).Replace(".jpg", "")));
                pt.Ellipse = el;

                ElEntity elTntiy = new ElEntity();
                elTntiy.PointElement = pt;
                pt.ElEntity = elTntiy;

                ToolTipService.SetToolTip(elTntiy, pt.Title);
                Canvas.SetLeft(elTntiy, pt.Point.X - pt.Radius / 2);
                Canvas.SetTop(elTntiy, pt.Point.Y - pt.Radius / 2);
                canvasDom.Children.Add(elTntiy);
            }

            //
            PointElement MyPt = myPoints[0];
            //将自己移除点集合
            myPoints.Remove(MyPt);
            IEnumerable<PointElement> friendPts = myPoints.Where(p => p != MyPt).OrderByDescending(p => p.Radius).Take(myPoints.Count > 21 ? random.Next(1, 20) : myPoints.Count);
            //联线
            List<PointElement> Pts = new List<PointElement>();
            //画联线
            foreach (PointElement pt in friendPts)
            {
                //找出控制点
                Point conPt = GetControl(MyPt.Point, pt.Point, myPoints);
                //我的好友是7px
                double width = 7;
                canvasLine.Children.Add(
                   pt.ElEntity.FromPath = PathCommon.Draw(
                    MyPt.Point,
                    conPt,
                    pt.Point
                    , MyPt.Color
                    , width
                    ));
                Pts.Add(pt);
                pt.ElEntity.From.Add(MyPt.ElEntity);
                MyPt.ElEntity.To.Add(pt.ElEntity);
            }


            //已经使用过的数据
            int taknum = 0;
            int olpts = Pts.Count;
            //开始画联线的联线
            foreach (PointElement Fpt in Pts)
            {
                var items = myPoints.Where(p => p != MyPt && !Pts.Contains(p)).ToList();
                int willtak = random.Next(1, ((items.Count() - taknum) / 2) < 1 ? 2 : ((items.Count() - taknum) / 2));
                //  willtak = items.Skip(willtak).Take(myPoints.Count).Count() / olpts; 
                //带走的数据越来越少
                foreach (PointElement pt in items.Skip(taknum).Take(olpts == 1 ? (items.Skip(taknum).Count() > willtak ? 9999 : willtak) : willtak))
                {
                    //找出控制点
                    Point conPt = GetControl(Fpt.Point, pt.Point, myPoints);
                    //我的联线的联线是3px
                    double width = 3;
                    //路径
                    Path path = PathCommon.Draw(Fpt.Point, conPt, pt.Point
                            , Fpt.Color
                            , width
                            );
                    pt.ElEntity.FromPath = path;
                    canvasLine.Children.Insert(0, path);

                    //添加到集合
                    Fpt.ElEntity.To.Add(pt.ElEntity);

                    pt.ElEntity.From.Add(Fpt.ElEntity);

                   //将二次联线弄成虚线
                    path.StrokeDashArray.Add(1);
                    path.StrokeDashArray.Add(0.5);
                    path.StrokeEndLineCap = PenLineCap.Round;
                    path.StrokeLineJoin = PenLineJoin.Round;

                }

                taknum += willtak;
                olpts -= 1;
            }

        }
        /// <summary>
        /// 找到控制点
        /// </summary>
        /// <param name="BasePt">开始</param>
        /// <param name="endPt">结束</param>
        /// <param name="pts">所有点集合</param>
        /// <returns></returns>
        protected Point GetControl(Point BasePt, Point endPt, IEnumerable<PointElement> pts)
        {
            Point conPt = BasePt;
            //找出控制点
            foreach (var p in pts)
            {
                if (CommMethods.IsPointInLine(p.Point, BasePt, endPt))
                {
                    conPt = p.Point;
                    break;
                }
            }
            return conPt;
        }

        #endregion
        /// <summary>
        /// 获取头像
        /// </summary>
        public string Photo
        {

            get
            {
                return "/imgs/" + random.Next(1, 66) + ".jpg";
            }
        }

        public string PhotoName(int index) {
            
           //用于生成随机名称的序列
                string[] source = @"尘封的记忆

醉生梦死.

拜拜·永远

短暂de幸福

你的美貌征服L我

微笑花向着谁

前尘忆梦う一世殇

我的生命χ在也挽回不了倪

何必当真、

硪要的，沵給卟了

刻苦铭心ヾ

转身含满泪

凉了心脏

离不开的影

月亮的向日葵

双、人舞

回忆，已不在

我的生命χ在也挽回不了倪

狗没你做作︶￣

怪我没出息

失去后的珍惜

哥、葶硫塬點

〣.顺唭_自然

多说也是无益

゛_ 绝 笔!、

（花容月貌〉

缄*默*花

玉丶　漱

°风轻云淡、

＊¨沫夕贝∞

℡↘流金岁月

甜蜜的牵手

前尘忆梦う一世殇

情归左岸

梦里的承诺

我看着你失眠

何必自演自醉

视伱如命

々梦一般的你♂

、﹏ 欲

╯歇斯底里

前尘忆梦う一世殇

#唇齿情话

低调不失高傲°

子弹穿过玫瑰花

谁可以照顾我

说好了玩心、却动了真情

心照不喧

落单旳翅膀

◇﹏悲劇№

转身℡拾泪

城南旧梦°

消失过的甜蜜

纯情有罪、

〔り只为n1而已

记忆切割线

Strangerつ

幸福的约定

我感觉不到你了/

格桑花 戰ぉ

转身丶说离别

跌落的繁华

﹏流白、半夏

丑人总装怪╮

心落凡尘

ゞ☆暇戏真做

自尊丶

我感觉不到你了/

我想更懂你丶

輕描淡寫調調

灰白格子。

转身℡拾泪

⊙︿⊙（郁闷）".Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

                return source[index];

            
        }

        #region 随机生成圆不重叠
        //用于生成随机数的功能 
        static Random random = new Random();
        /// <summary>
        /// 在一个指定大小的区域里生成不重叠的圆
        /// </summary>
        /// <param name="canvasWidth">画布宽</param>
        /// <param name="canvasHeight">画布高</param>
        /// <param name="Num">生成数量</param>
        /// <param name="SpaceMin">最小间距</param>
        /// <param name="RadiusMin">最小半径</param>
        /// <param name="RadiusMax">最大半径</param>
        ///<returns>返回创建后的点对像,如果区域不够由抛出异常</returns>
        public List<PointElement> CreateFraments(double canvasWidth, double canvasHeight, int Num, double SpaceMin = 10, double RadiusMin = 25, double RadiusMax = 100)
        {


            double myNumber = Num; //数量
            double minSpace = SpaceMin; // 最小间距；
            //最大半径
            double maxRadius = RadiusMax;
            //最小半径；
            double minRadius = RadiusMin;

            ///看看画布能不能画下原素
            double myWidth = canvasWidth > Num * (minSpace) * 1.3 ? canvasWidth : Num * (minSpace) * 1.3;
            double myHeight = canvasHeight > Num * (minSpace) * 1.3 ? canvasHeight : Num * (minSpace) * 1.37;


            ///用于返回的点对像集合
            List<PointElement> myPoints = new List<PointElement>();

            ////定义循环警告限度
            var myWarning = 5 * 1000 * 1000 * 2;

            int i = 0;
            int go = 0;
            bool okGo = true;
            int warning = myWarning;

            //添加默认点

            myPoints.Add(new PointElement()
            {
                Point = new Point(myWidth / 2, myHeight / 2),
                Radius = 125,
            });

            while (i < myNumber && okGo)
            {
                //标识当前状态
                bool ok = true;
                double minDistance = maxRadius;
                double centerX = Math.Round(double.Parse("0." + random.Next(1, int.MaxValue)) * myWidth);
                double centerY = Math.Round(double.Parse("0." + random.Next(1, int.MaxValue)) * myHeight);

                for (int j = 0; j < myPoints.Count; j++)
                {
                    //下页这些用来判断位置
                    double nowDistance =
                        Math.Sqrt(Math.Pow(centerX - myPoints[j].Point.X, 2)
                        +
                        Math.Pow(centerY - myPoints[j].Point.Y, 2))
                        //半径
                        - myPoints[j].Radius / 2 - minSpace;
                    minDistance = nowDistance < minDistance ? nowDistance : minDistance;
                    if (minDistance < minRadius)
                    {
                        ok = false;
                        break;
                    }
                }
                if (ok)
                {
                    //临时生成一个半径用于保存数据的变量
                    double sRadius = 0.0;

                    //判断随机还是紧密
                    //if (true)
                    //{ 
                    sRadius = minDistance;
                    //}
                    //else
                    //{
                    //    sRadius = minDistance * (1 - double.Parse("0." + random.Next(1, int.MaxValue)));
                    //}
                    //最后的半径变量
                    double endRadius = sRadius > minRadius ? sRadius : minRadius;
                    PointElement pt = new PointElement()
                    {
                        Point = new Point(centerX, centerY),
                        Radius = endRadius,
                    };
                    myPoints.Add(pt);
                    i++;
                    warning = myWarning;
                    go = 0;
                }
                go++;
                if (go >= warning)
                {
                    okGo = MessageBox.Show("在试图确定第" + (i + 1) + "个对象时已经进行了" + go + "次尝试，是否继续？\r\n继续则可能陷入死循环。", "", MessageBoxButton.OKCancel) == MessageBoxResult.OK;
                    if (okGo)
                    {
                        warning += myWarning;
                    };
                    throw new ArgumentOutOfRangeException("生成随机点超过最大命中次数限制,请将长宽修改更大或者减少生成数量");
                }
            }
            //用于扩展当前产生点的属性
            foreach (PointElement pt in myPoints)
            {

                //产生随机颜色
                byte[] bytArr = Guid.NewGuid().ToByteArray();
                List<byte> cloorArr = bytArr.Where(p => (int)p > 50).ToList();
                while (cloorArr.Count<= 3)
                {
                    cloorArr.AddRange(Guid.NewGuid().ToByteArray().Where(p => (int)p > 50));
                }



                //颜色随机颜色
                Color color = Color.FromArgb(0xff, cloorArr[0], cloorArr[1], cloorArr[2]);
                pt.Color = color;

                //产生对应半径的边框线条宽度
                pt.StrokeThickness = pt.Radius / 12.5 > 2 ? pt.Radius / 12.5 : 2;

            }


            return myPoints;


        }
        #endregion

        /// <summary>
        /// Key
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_KeyDown_1(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.F8)
            {
                canvasDom.Children.Clear();
                canvasLine.Children.Clear();
                canvasSelectDom.Children.Clear();
                canvasSelectLine.Children.Clear();
                CloseLight.Visibility = System.Windows.Visibility.Collapsed;
                  SelectObjet = null;
                //画圆
                DrawEllipse();
            }
        }



        #region 选中功能

        /// <summary>
        /// 锁功能
        /// </summary>
        public object LockObject = new object();
        ElEntity SelectObjet = null;

        /// <summary>
        /// 线的效果 
        /// </summary>
        public System.Windows.Media.Effects.DropShadowEffect DropShad = new System.Windows.Media.Effects.DropShadowEffect()
        {
            BlurRadius=15,
             Color = Colors.Yellow,
              Direction=0,
             ShadowDepth=0,
              
        };
        /// <summary>
        /// 选中对像
        /// </summary>
        /// <param name="selectObjet"></param>
        public void OnSelect(ElEntity selectObjet)
        {
            ClearSelect();
            lock (LockObject)
            {
                //将选中项与选中项的线高亮显示
                //1.将相当的原素从原来的图层 中删除
                //2.将相关的原素画到新的图层当中
                if (selectObjet != null)
                {
                    SelectObjet = selectObjet;
                    foreach (var item in selectObjet.From)
                    {
                        lock (item)
                        {
                            item.Effect = DropShad;
                            //头像
                            canvasDom.Children.Remove(item);
                            if (item.Parent != canvasSelectDom)
                            {
                                canvasSelectDom.Children.Add(item);
                            }
                            ////联线
                            //if (item.FromPath != null)
                            //{
                            //    lock (item.FromPath)
                            //    {
                            //        item.FromPath.Effect = DropShad;
                            //        canvasLine.Children.Remove(item.FromPath);
                            //        if (item.FromPath.Parent != canvasSelectLine)
                            //        {
                            //            canvasSelectLine.Children.Add(item.FromPath);
                            //        }
                            //    }
                            //}
                        }
                    }
                    foreach (var item in selectObjet.To)
                    {
                        lock (item)
                        {
                            item.Effect = DropShad;
                            //头像
                            canvasDom.Children.Remove(item);
                            if (item.Parent != canvasSelectDom)
                            {
                                canvasSelectDom.Children.Add(item);
                            }
                            //联线
                            if (item.FromPath != null)
                            {
                               
                                lock (item.FromPath)
                                {
                                    item.FromPath.Effect = DropShad;
                                    canvasLine.Children.Remove(item.FromPath);
                                    if (item.FromPath.Parent != canvasSelectLine)
                                    {
                                        canvasSelectLine.Children.Add(item.FromPath);
                                    }
                                }
                            }
                        }
                    }
                    //自己
                    lock (SelectObjet)
                    {
                        SelectObjet .Effect = DropShad;
                        //头像
                        canvasDom.Children.Remove(SelectObjet);
                        if (SelectObjet.Parent != canvasSelectDom)
                        {
                            canvasSelectDom.Children.Add(SelectObjet);
                        }
                        //联线
                        if (SelectObjet.FromPath != null)
                        {
                            lock (SelectObjet.FromPath)
                            {
                                SelectObjet.FromPath.Effect = DropShad;
                                canvasLine.Children.Remove(SelectObjet.FromPath);
                                if (SelectObjet.FromPath.Parent != canvasSelectLine)
                                {
                                    canvasSelectLine.Children.Add(SelectObjet.FromPath);
                                }
                            }
                        }
                    }

                }
            }
        }
        /// <summary>
        /// 清空选择
        /// </summary>
        public void ClearSelect()
        {
            lock (LockObject)
            {
                canvasSelectLine.Children.Clear();
                canvasSelectDom.Children.Clear();
                if (SelectObjet != null)
                {

                    foreach (var item in SelectObjet.From)
                    {
                        lock (item)
                        {
                            item.Effect = null;
                            //头像
                            canvasSelectLine.Children.Remove(item);
                            if (item.Parent != canvasDom)
                            {
                                canvasDom.Children.Add(item);
                            }
                            ////联线
                            //if (item.FromPath != null)
                            //{
                            //    lock (item.FromPath)
                            //    {
                            //        item.FromPath.Effect = null;
                            //        canvasSelectLine.Children.Remove(item.FromPath);
                            //        if (item.FromPath.Parent != canvasLine)
                            //        {
                            //            canvasLine.Children.Add(item.FromPath);
                            //        }
                            //    }
                            //}
                        }
                    }
                    foreach (var item in SelectObjet.To)
                    {
                        lock (item)
                        {
                            item.Effect = null;
                            //头像
                            canvasSelectLine.Children.Remove(item);
                            if (item.Parent != canvasDom)
                            {
                                canvasDom.Children.Add(item);
                            }

                            //联线
                            if (item.FromPath != null)
                            {
                                lock (item.FromPath)
                                {
                                    item.FromPath.Effect = null;
                                    canvasSelectLine.Children.Remove(item.FromPath);
                                    if (item.FromPath.Parent != canvasLine)
                                    {
                                        canvasLine.Children.Add(item.FromPath);
                                    }
                                }
                            }
                        }
                    }

                    //自己
                    lock (SelectObjet)
                    {
                        SelectObjet.Effect = null ;
                        //头像
                        canvasSelectLine.Children.Remove(SelectObjet);
                        if (SelectObjet.Parent != canvasDom)
                        {
                            canvasDom.Children.Add(SelectObjet);
                        }

                        //联线
                        if (SelectObjet.FromPath != null)
                        {
                            lock (SelectObjet.FromPath)
                            {
                                SelectObjet.FromPath.Effect = null;
                                canvasSelectLine.Children.Remove(SelectObjet.FromPath);
                                if (SelectObjet.FromPath.Parent != canvasLine)
                                {
                                    canvasLine.Children.Add(SelectObjet.FromPath);
                                }
                            }
                        }
                    }

                }
            }
        }

        #endregion

        #region 平移
        #region 窗口移动

         bool isSecect = false;//是否选中
         Point startPoint = new Point();//开始坐标
         FrameworkElement currentElement = null;//要拖动的控件
        //鼠标抬起
        public  void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (isSecect)
            {
                currentElement.ReleaseMouseCapture();//移除鼠标捕获
            }
            isSecect = false;
        }

        //鼠标按下
        public  void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            currentElement = (sender as FrameworkElement);//获取要拖动的控件
            currentElement.CaptureMouse();//鼠标捕获
            isSecect = true;//选中
            startPoint = e.GetPosition(null);//获取当前坐标
        }

        //鼠标移动
        public  void MouseMove(object sender, MouseEventArgs e)
        {
            if (isSecect)
            {
                Point pt = e.GetPosition(null);//获取当前坐标
    
                              //获取鼠标当前位置

                double currX = e.GetPosition(null).X;

                double currY = e.GetPosition(null).Y;

                //获取当前图形的位置

                double currLeft = (double)((UIElement)can ).GetValue(Canvas.LeftProperty);

                double currTop = (double)((UIElement)can).GetValue(Canvas.TopProperty);

                //移动当前图形的位置

((UIElement)can).SetValue(Canvas.LeftProperty, currLeft + currX - startPoint.X);

                ((UIElement)can).SetValue(Canvas.TopProperty, currTop + currY - startPoint.Y);

 
                    startPoint = pt;//把当前坐标获取为起始坐标
                }
            }
        
        #endregion
  
        #endregion
    }
}
